package com.mall.order.mq.order;

import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.*;
import com.mall.order.dal.persistence.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/*
 * @description: 消息订单延时消费者
 */
@Slf4j
@Component
public class DelayOrderConsumer {

    private DefaultMQPushConsumer mqPushConsumer;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    StockMapper stockMapper;

    @Autowired
    ItemMapper itemMapper;

    @Autowired
    PromoSessionMapper promoSessionMapper;

    @Autowired
    PromoItemMapper promoItemMapper;

    @PostConstruct
    public void init() {
        mqPushConsumer = new DefaultMQPushConsumer("delay_order_consumer");
        mqPushConsumer.setNamesrvAddr("127.0.0.1:9876");

        try {
            mqPushConsumer.subscribe("delay_order_cancel", "*");

            //消息监听器
            mqPushConsumer.setMessageListener(new MessageListenerConcurrently() {
                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {

                    //从消息中取出id
                    MessageExt message = list.get(0);
                    byte[] body = message.getBody();
                    String orderId = new String(body, 0, body.length);


                    Order order = orderMapper.selectByPrimaryKey(orderId);

                    //如果已经查询不到订单了，说明订单已经被删除
                    if (order == null) {
                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                    }
                    //查询订单是否支付成功，如果支付成功什么都不做
                    Integer status = order.getStatus();
                    if (status == OrderConstants.ORDER_STATUS_PAYED) {
                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                    }

                    //如果未支付且取消订单就什么也不用做
                    if (status == OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL) {
                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                    }

                    //如果未支付，订单取消，并返回库存
                    //1.修改order表status
                    order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
                    order.setUpdateTime(new Date());
                    orderMapper.updateByPrimaryKeySelective(order);
                    //2.通过orderItem表查该订单中的所有item
                    List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
                    //3.通过item修改stock表stock_count,lock_count
                    for (OrderItem orderItem : orderItems) {
                        //将item表中该订单的所有item的status改为2库存已释放状态
                        orderItemMapper.updateStockStatus(2, orderId);

                        //判断是否为秒杀商品，如果是秒杀商品将返回秒杀商品的库存
                        String sessionId = "1";
                        Calendar calendar = Calendar.getInstance();
                        int hour = calendar.get(Calendar.HOUR_OF_DAY);
                        if (hour >= 16) {
                            sessionId = "2";
                        }
                        String yyyyMMdd = new SimpleDateFormat("yyyyMMdd").format(new Date());

                        //通过价格去判断是否为秒杀商品 //TODO 最好用标志位
                        Long itemId = orderItem.getItemId();
                        Item item = itemMapper.selectByPrimaryKey(itemId);
                        double price = orderItem.getPrice();
                        double value = item.getPrice().doubleValue();

                        if (price < value) {
                            //如果价格不相等说明是秒杀商品
                            //通过时间和sessionId定位场次-->再通过商品Id和场次找到秒杀详情表，库存+1
                            Example example = new Example(PromoSession.class);
                            example.createCriteria()
                                    .andEqualTo("sessionId", sessionId)
                                    .andEqualTo("yyyymmdd", yyyyMMdd);
                            List<PromoSession> promoSessions = promoSessionMapper.selectByExample(example);
                            PromoSession promoSession = promoSessions.get(0);
                            //获得场次Id和产品Id
                            Long psId = promoSession.getId();
                            //更新代码库存+1的mapper重写了
                            promoItemMapper.increaseStock(itemId, psId);

                        } else {
                            //通过商品id找到库存
                            Stock stock = stockMapper.selectStock(orderItem.getItemId());
                            //修改更新库存的库存数量
                            stock.setStockCount(orderItem.getNum().longValue());
                            stock.setLockCount(-orderItem.getNum());
                            stockMapper.updateStock(stock);
                        }
                    }
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });

            mqPushConsumer.start();

        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }
}
